package ciyuan.wrap;

import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static ciyuan.QQLogin.PREFIX;

public class BKWrap extends Wrapper {

    private final BKMain plugin;

    public BKWrap(Object plugin) {
        this.plugin = (BKMain) plugin;
    }

    @Override
    public void reloadConfig() {
        plugin.reloadConfig();
    }

    @Override
    public void logMsg(String msg) {
        Bukkit.getConsoleSender().sendMessage(PREFIX + msg);
    }

    @Override
    public boolean playerIsOnline(String playerName) {
        Player player = Bukkit.getPlayer(playerName);
        return player != null && player.isOnline();
    }

    @Override
    public File getDataFolder() {
        return plugin.getDataFolder();
    }

    @Override
    public boolean isOp(String playerName) {
        Player player = Bukkit.getPlayer(playerName);
        return player != null && player.isOp();
    }

    @Override
    public void asyncKickPlayer(String playerName, String reason) {
        new BukkitRunnable() {
            @Override
            public void run() {
                Player player = Bukkit.getPlayer(playerName);
                if (player != null && player.isOnline() && !playerName.isEmpty()) {
                    player.kickPlayer(reason);
                }
            }
        }.runTaskLater(plugin, 1L);
    }

    @Override
    public void disableCurrentPlugin() {
        Bukkit.getPluginManager().disablePlugin(plugin);
    }

    @Override
    public boolean hasPermission(String playerName, String permission) {
        Player player = Bukkit.getPlayer(playerName);
        return player != null && player.hasPermission(permission);
    }

    @Override
    public List<String> getOnlinePlayerNames() {
        return Bukkit.getOnlinePlayers().stream().filter(Player::isOnline).map(Player::getName).collect(Collectors.toList());
    }

    @Override
    public Object loadConfig() {
        try {
            return plugin.getConfig();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void saveConfig(Object config) {
        try {
            ((YamlConfiguration) config).options().copyDefaults(true);
            plugin.saveConfig();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object loadConfiguration(File dataFile) {
        try {
            return YamlConfiguration.loadConfiguration(dataFile);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void saveConfiguration(Object config, File dataFile) throws IOException {
        ((YamlConfiguration) config).save(dataFile);
    }

    @Override
    public boolean configContainsKey(Object config, String key) {
        return ((YamlConfiguration) config).contains(key);
    }

    @Override
    public void configSetValue(Object config, String key, Object value) {
        ((YamlConfiguration) config).set(key, value);
    }

    @Override
    public List<String> configGetStringList(Object config, String key) {
        return ((YamlConfiguration) config).getStringList(key);
    }

    @Override
    public String configGetString(Object config, String key) {
        return ((YamlConfiguration) config).getString(key);
    }

    @Override
    public int configGetInt(Object config, String key) {
        return ((YamlConfiguration) config).getInt(key);
    }

    @Override
    public long configGetLong(Object config, String key) {
        return ((YamlConfiguration) config).getLong(key);
    }

    @Override
    public boolean configGetBoolean(Object config, String key) {
        return ((YamlConfiguration) config).getBoolean(key);
    }

    @Override
    public void configAddDefault(Object config, String key, Object value) {
        ((YamlConfiguration) config).addDefault(key, value);
    }

    @Override
    public String getPluginVersion() {
        return plugin.getDescription().getVersion();
    }

    @Override
    public void sendMsgToSender(Object sender, String msg) {
        ((org.bukkit.command.CommandSender) sender).sendMessage(msg);
    }

    @Override
    public int getGameServerPort() {
        return plugin.getServer().getPort();
    }

    @Override
    public String getServerVersion() {
        return Bukkit.getName() + " " + Bukkit.getBukkitVersion();
    }

    @Override
    public Map<String, String> getOnlinePlayerAddress() {
        return Bukkit.getOnlinePlayers()
            .stream()
            .collect(Collectors.toMap(Player::getName, player -> player.getAddress().toString(), (old, next) -> next));
    }

    static class CommandReceiver implements CommandSender {
        private String result;

        public String getResult() {
            return result;
        }

        @Override
        public void sendMessage(String s) {
            result = s;
        }

        @Override
        public void sendMessage(String[] strings) {}

        @Override
        public Server getServer() {
            return null;
        }

        @Override
        public String getName() {
            return PREFIX;
        }

        @Override
        public Spigot spigot() {
            return null;
        }

        @Override
        public boolean isPermissionSet(String s) {
            return false;
        }

        @Override
        public boolean isPermissionSet(Permission permission) {
            return false;
        }

        @Override
        public boolean hasPermission(String s) {
            return true;
        }

        @Override
        public boolean hasPermission(Permission permission) {
            return true;
        }

        @Override
        public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b) {
            return null;
        }

        @Override
        public PermissionAttachment addAttachment(Plugin plugin) {
            return null;
        }

        @Override
        public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b, int i) {
            return null;
        }

        @Override
        public PermissionAttachment addAttachment(Plugin plugin, int i) {
            return null;
        }

        @Override
        public void removeAttachment(PermissionAttachment permissionAttachment) {}

        @Override
        public void recalculatePermissions() {}

        @Override
        public Set<PermissionAttachmentInfo> getEffectivePermissions() {
            return null;
        }

        @Override
        public boolean isOp() {
            return true;
        }

        @Override
        public void setOp(boolean b) {}
    }

    @Override
    public String executeCommand(String command) {
        CommandReceiver commandReceiver = new CommandReceiver();
        Bukkit.dispatchCommand(commandReceiver, command);
        return commandReceiver.getResult();
    }
}
